Section 4.3
Simple Shapes

So far we have just used the sphere shape. There are many other types of shapes that can be rendered by POV-Ray. The following sections will describe how to use some of the more simple objects as a replacement for the sphere used above.

Section 4.3.1
Box Object

The box is one of the most common objects used. We try this example in place of the sphere:

box { <-1, 0, -1>, // Near lower left corner < 1, 0.5, 3> // Far upper right corner texture { T_Stone25 // Pre-defined from stones.inc scale 4 // Scale by the same amount in all // directions } rotate y*20 // Equivalent to "rotate <0,20,0>" }

In the example we can see that a box is defined by specifying the 3D coordinates of its opposite corners. The first vector must be the minimum x-, y- and z-coordinates and the 2nd vector must be the maximum x-, y- and z-values. Box objects can only be defined parallel to the axes of the world coordinate system. We can later rotate them to any angle. Note that we can perform simple math on values and vectors. In the rotate parameter we multiplied the vector identifier y by 20. This is the same as <0,1,0>*20 or <0,20,0>.


Section 4.3.2
Cone Object

Here's another example showing how to use a cone:

cone { <0, 1, 0>, 0.3 // Center and radius of one end <1, 2, 3>, 1.0 // Center and radius of other end texture { T_Stone25 scale 4 } }

The cone shape is defined by the center and radius of each end. In this example one end is at location <0,1,0> and has a radius of 0.3 while the other end is centered at <1,2,3> with radius=1. If we want the cone to come to a sharp point we must use radius=0. The solid end caps are parallel to each other and perpendicular to the cone axis. If we want an open cone with no end caps we have to add the keyword open after the 2nd radius like this:

cone { <0, 1, 0>, 0.3 // Center and radius of one end <1, 2, 3>, 1.0 // Center and radius of other end open // Removes end caps texture { T_Stone25 scale 4 } }

Section 4.3.3
Cylinder Object

We may also define a cylinder like this:

cylinder { <0, 1, 0>, // Center of one end <1, 2, 3>, // Center of other end 0.5 // Radius open // Remove end caps texture { T_Stone25 scale 4 } }

Section 4.3.4
Plane Object

Let's try out a computer graphics standard - The Checkered Floor. We add the following object to the first version of the demo.pov file, the one including the sphere.

plane { <0, 1, 0>, -1 pigment { checker color Red, color Blue } }

The object defined here is an infinite plane. The vector <0,1,0> is the surface normal of the plane (i.e. if we were standing on the surface, the normal points straight up). The number afterward is the distance that the plane is displaced along the normal from the origin - in this case, the floor is placed at y=-1 so that the sphere at y=1, radius=2, is resting on it.

We note that even though there is no texture statement there is an implied texture here. We might find that continually typing statements that are nested like texture {pigment} can get to be tiresome so POV-Ray let's us leave out the texture statement under many circumstances. In general we only need the texture block surrounding a texture identifier (like the T_Stone25 example above), or when creating layered textures (which are covered later).

This pigment uses the checker color pattern and specifies that the two colors red and blue should be used.

Because the vectors <1,0,0>, <0,1,0> and <0,0,1> are used frequently, POV-Ray has three built-in vector identifiers x, y and z respectively that can be used as a shorthand. Thus the plane could be defined as:

plane { y, -1 pigment { ... } }

Note that we do not use angle brackets around vector identifiers.

Looking at the floor, we notice that the ball casts a shadow on the floor. Shadows are calculated very accurately by the ray-tracer, which creates precise, sharp shadows. In the real world, penumbral or "soft" shadows are often seen. Later we will learn how to use extended light sources to soften the shadows.


Section 4.3.5
Standard Include Objects

The standard include file shapes.inc contains some pre-defined shapes that are about the size of a sphere with a radius of one unit. We can invoke them like this:

#include "shapes.inc" object { UnitBox texture { T_Stone25 scale 4 } scale 0.75 rotate <-20,25,0> translate y }

Section 4.4
Advanced Shapes

After we have gained some experience with the simpler shapes available in POV-Ray it is time to go on to the more advanced, thrilling shapes.

We should be aware that the shapes described below are not trivial to understand. We needn't be worried though if we do not know how to use them or how they work. We just try the examples and play with the features described in the reference chapter. There is nothing better than learning by doing.


Section 4.4.1
Bicubic Patch Object

Bicubic or Bezier patches are useful surface representations because they allow an easy definition of surfaces using only a few control points. The control points serve to determine the shape of the patch. Instead of defining the vertices of triangles, we simply give the coordinates of the control points. A single patch has 16 control points, four at each corner, and the rest positioned to divide the patch into smaller sections. For ray-tracing (or rendering) the patches are approximated using triangles. Bezier patches are almost always created using a third party modeller so for this tutorial, we will use moray (any other modeller that supports Bezier patches and POV-Ray can also be used). We will use moray only to create the patch itself, not the other elements of the scene.

Bezier patches are actually very useful and, with a little practice, some pretty amazing things can be created with them. For our first tutorial, let's make a sort of a teepee/tent shape using a single sheet patch.

First, we start moray and, from the main edit screen, we click on "CREATE". We Name our object Teepee. The "CREATE BEZIER PATCH" dialogue box will appear. We have to make sure that "SHEET" is depressed. We click on "OK, CREATE". At the bottom of the main edit screen, we click on "EXTENDED EDIT".

We hold the cursor over the "TOP" view and right click to make the pop-up menu appear. We click on "MAXIMIZE". We [ALT]-drag to zoom in a little. We click on "MARK ALL", and under the transformation mode box, "UFRM SCL". We drag the mouse to scale the patch until it is approximately four units wide. We click on "TRANSLATE", and move the patch so that its center is over the origin. We right click "MINIMIZE" and "UNMARK ALL".

We [SHIFT]-drag a box around the lower right control point to mark it. We [ALT]-zoom into the "FRONT" view so that we can see the patch better. In the "FRONT" view, we "TRANSLATE" that point 10 units along the negative z-axis (we note that in MORAY z is up). We "UNMARK ALL". We repeat this procedure for each of the other three corner points. We make sure we remember to "UNMARK ALL" once each point has been translated. We should have a shape that looks as though it is standing on four pointed legs. We "UNMARK ALL".

Working once again in the "TOP" view, we [SHIFT]-drag a box around the four center control points to mark them. We right-click over the "TOP" view and "MAXIMIZE". We click on "UFRM SCL" and drag the mouse to scale the four points close together. We [ALT]-drag to zoom closer and get them as close together as we can. We [ALT]-drag to zoom out, right click and "MINIMIZE".

In the "FRONT" view, we "TRANSLATE" the marked points 10 units along the positive z-axis. We "UNMARK ALL". The resulting shape is quite interesting, was simple to model, and could not be produced using CSG primitives. Now let's use it in a scene.

We click on "DONE" to return to the main edit screen. We note that U_STEPS and V_STEPS are both set to 3 and flatness is set to 0.01. We leave them alone for now. We click on "FILES" and then "SAVE SEL" (save selection). We name our new file teepee1.mdl. We press [F3] and open teepee1.mdl. There is no need to save the original file. When teepee1 is open, we create a quick "dummy" texture (moray will not allow us to export data without a texture). We use white with default finish and name it TeePeeTex. We apply it to the object, save the file and press [CTRL-F9]. moray will create two files: teepee1.inc and teepee1.pov.

We exit moray and copy teepee1.inc and teepee1.pov into our working directory where we are doing these tutorials. We create a new file called bezdemo.pov and edit it as follows:

#include "colors.inc" camera { location <0, .1, -60> look_at 0 angle 40 } background { color Gray25 } //to make the patch easier to see light_source { <300, 300, -700> White } plane { y, -12 texture { pigment { checker color Green color Yellow } } }

Using a text editor, we create and declare a simple texture for our teepee object:

#declare TeePeeTex = texture { pigment { color rgb <1, 1, 1,> } finish { ambient .2 diffuse .6 } }

We paste in the bezier patch data from teepee1.pov (the additional object keywords added by moray were removed):

bicubic_patch { type 1 flatness 0.0100 u_steps 3 v_steps 3, <-5.174134, 5.528420, -13.211995>, <-1.769023, 5.528420, 0.000000>, <1.636088, 5.528420, 0.000000>, <5.041199, 5.528420, -13.003932>, <-5.174134, 1.862827, 0.000000>, <0.038471, 0.031270, 18.101474>, <0.036657, 0.031270, 18.101474>, <5.041199, 1.862827, 0.000000>, <-5.174134, -1.802766, 0.000000>, <0.038471, 0.028792, 18.101474>, <0.036657, 0.028792, 18.101474>, <5.041199, -1.802766, 0.000000>, <-5.174134, -5.468359, -13.070366>, <-1.769023, -5.468359, 0.000000>, <1.636088, -5.468359, 0.000000>, <4.974128, -5.468359, -12.801446> texture { TeePeeTex } rotate -90*x // to orient the object to LHC rotate 25*y // to see the four "legs" better }

We add the above rotations so that the patch is oriented to POV-Ray's left-handed coordinate system (remember the patch was made in moray in a right handed coordinate system), so we can see all four legs. Rendering this at 200x150 -a we see pretty much what we expect, a white teepee over a green and yellow checkered plane. Let's take a little closer look. We render it again, this time at 320x200.

Now we see that something is amiss. There appears to be sharp angling, almost like faceting, especially near the top. This is indeed a kind of faceting and is due to the U_STEPS and V_STEPS parameters. Let's change these from 3 to 4 and see what happens.

That's much better, but it took a little longer to render. This is an unavoidable tradeoff. If we want even finer detail, we must use a U_STEPS and V_STEPS value of 5 and set flatness to 0. But we must expect to use lots of memory and an even longer tracing time.

Well, we can't just leave this scene without adding a few items just for interest. We declare the patch object and scatter a few of them around the scene:

#declare TeePee = bicubic_patch { type 1 flatness 0.0100 u_steps 3 v_steps 3, <-5.174134, 5.528420, -13.211995>, <-1.769023, 5.528420, 0.000000>, <1.636088, 5.528420, 0.000000>, <5.041199, 5.528420, -13.003932>, <-5.174134, 1.862827, 0.000000>, <0.038471, 0.031270, 18.101474>, <0.036657, 0.031270, 18.101474>, <5.041199, 1.862827, 0.000000>, <-5.174134, -1.802766, 0.000000>, <0.038471, 0.028792, 18.101474>, <0.036657, 0.028792, 18.101474>, <5.041199, -1.802766, 0.000000>, <-5.174134, -5.468359, -13.070366>, <-1.769023, -5.468359, 0.000000>, <1.636088, -5.468359, 0.000000>, <4.974128, -5.468359, -12.801446> texture { TeePeeTex } rotate -90*x // to orient the object to LHC rotate 25*y // to see the four "legs" better } object { TeePee } object { TeePee translate <8, 0, 8> } object { TeePee translate <-9, 0, 9> } object { TeePee translate <18, 0, 24> } object { TeePee translate <-18, 0, 24> }

That looks good. Let's do something about that boring gray background. We delete the background declaration and replace it with:

plane { y, 500 texture { pigment { SkyBlue } finish { ambient 1 diffuse 0} } texture { pigment { bozo turbulence .5 color_map { [0 White] [1 White filter 1] } } finish { ambient 1 diffuse 0 } scale <1000, 250, 250> rotate <5, 45, 0> } }

This adds a pleasing cirrus-cloud filled sky. Now, let's change the checkered plane to rippled sand dunes:

plane {y,-12 texture { pigment { color <.85, .5, .15> } finish { ambient .25 diffuse .6 crand .5 } normal { ripples .35 turbulence .25 frequency 5 } scale 10 translate 50*x } }

We render this at 320x240 -a. Not bad! Let's just add one more element. Let's place a golden egg under each of the teepees. And since this is a bezier patch tutorial, let's make the eggs out of bezier patches.

We return to moray and create another bezier patch. We name it Egg1 and select "CYLINDRICAL 2 - PATCH" from the "CREATE BEZIER PATCH" dialogue box. We click on "EXTENDED EDIT". We "MARK ALL" and rotate the patch so that the cylinder lays on its side. We "UNMARK ALL". In the "FRONT" view, we [SHIFT]-drag a box around the four points on the right end to mark them. In the "SIDE" view, we right click and "MAXIMIZE". We [ALT]-drag to zoom in a little closer. We "UFRM SCL" the points together as close as possible. We zoom in closer to get them nice and tight. We zoom out, right click and "MINIMIZE".

We click on "TRANSLATE" and drag the points to the left so that they are aligned on the z-axis with the next group of four points. This should create a blunt end to the patch. We repeat this procedure for the other end. We "UNMARK ALL".

In the "FRONT" view, the control grid should be a rectangle now and the patch should be an ellipsoid. We [SHIFT]-drag a box around the upper right corner of the control grid to mark those points. We then [SHIFT]-drag a box around the lower right corner to mark those points as well. In the "SIDE" view, we "UFRM SCL" the points apart a little to make that end of the egg a little wider than the other. We "UNMARK ALL".

The egg may need a little proportional adjustment. We should be able to "MARK ALL" and "LOCAL SCL" in the three views until we get it to look like an egg. When we are satisfied that it does, we "UNMARK ALL" and click on done. Learning from our teepee object, we now go ahead and change U_STEPS and V_STEPS to 4.

We create a dummy texture, white with default finish, name it EggTex and apply it to the egg. From the FILES menu, we "SAVE SEL" to filename egg1.mdl. We load this file and export ([CTRL F9]). We exit moray and copy the files egg1.inc and egg1.pov into our working directory.

Back in bezdemo.pov, we create a nice, shiny gold texture:

#declare EggTex = texture { pigment { BrightGold } finish { ambient .1 diffuse .4 specular 1 roughness 0.001 reflection .5 metallic } }

And while we're at it, let's dandy up our TeePeeTex texture:

#declare TeePeeTex = texture { pigment { Silver } finish { ambient .1 diffuse .4 specular 1 roughness 0.001 reflection .5 metallic } }

Now we paste in our egg patch data and declare our egg:

#declare Egg = union { // Egg1 bicubic_patch { type 1 flatness 0.0100 u_steps 4 v_steps 4, <2.023314, 0.000000, 4.355987>, <2.023314, -0.000726, 4.355987>, <2.023312, -0.000726, 4.356867>, <2.023312, 0.000000, 4.356867>, <2.032037, 0.000000, 2.734598>, <2.032037, -1.758562, 2.734598>, <2.027431, -1.758562, 6.141971>, <2.027431, 0.000000, 6.141971>, <-1.045672, 0.000000, 3.281572>, <-1.045672, -1.758562, 3.281572>, <-1.050279, -1.758562, 5.414183>, <-1.050279, 0.000000, 5.414183>, <-1.044333, 0.000000, 4.341816>, <-1.044333, -0.002947, 4.341816>, <-1.044341, -0.002947, 4.345389>, <-1.044341, 0.000000, 4.345389> } bicubic_patch { type 1 flatness 0.0100 u_steps 4 v_steps 4, <2.023312, 0.000000, 4.356867>, <2.023312, 0.000726, 4.356867>, <2.023314, 0.000726, 4.355987>, <2.023314, 0.000000, 4.355987>, <2.027431, 0.000000, 6.141971>, <2.027431, 1.758562, 6.141971>, <2.032037, 1.758562, 2.734598>, <2.032037, 0.000000, 2.734598>, <-1.050279, 0.000000, 5.414183>, <-1.050279, 1.758562, 5.414183>, <-1.045672, 1.758562, 3.281572>, <-1.045672, 0.000000, 3.281572>, <-1.044341, 0.000000, 4.345389>, <-1.044341, 0.002947, 4.345389>, <-1.044333, 0.002947, 4.341816>, <-1.044333, 0.000000, 4.341816> } texture { EggTex } translate <0.5, 0, -5> // centers the egg around the origin translate -9.8*y // places the egg on the ground }

We now place a copy of the egg under each teepee. This should require only the x- and z-coordinates of each teepee to be changed:

object { Egg } object { Egg translate <8, 0, 8> } object { Egg translate <-9, 0, 9> } object { Egg translate <18, 0, 24> } object { Egg translate <-18, 0, 24> }


Scene build with different Bezier patches.

We render this at 320x240 -A. Everything looks good so we run it again at 640x480 +A. Now we see that there is still some faceting near the top of the teepees and on the eggs as well. The only solution is to raise U_STEPS and V_STEPS from 4 to 5 and set flatness to 0 for all our bezier objects. We make the changes and render it again at 640x480 +A.


Next Section
Table Of Contents